package com.ruoyi.system.service.impl.trade;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.common.CargoStateConstant;
import com.ruoyi.system.common.WarehouseStateConstant;
import com.ruoyi.system.domain.db.basic.BasicWarehouses;
import com.ruoyi.system.domain.db.trade.TradeCargoOrder;
import com.ruoyi.system.domain.db.warehousestate.OrderWarehouseState;
import com.ruoyi.system.domain.dto.OrderWarehouseStateDto;
import com.ruoyi.system.domain.dto.TradeCargoOrderDto;
import com.ruoyi.system.domain.vo.OrderWarehouseStateVo;
import com.ruoyi.system.domain.vo.TradeCargoOrderVo;
import com.ruoyi.system.domain.vo.TransportTaskVo;
import com.ruoyi.system.mapper.basic.BasicWarehousesMapper;
import com.ruoyi.system.mapper.trade.TradeCargoOrderMapper;
import com.ruoyi.system.mapper.warehousestate.OrderWarehouseStateMapper;
import com.ruoyi.system.service.ITradeCargoOrderService;
import com.ruoyi.system.service.impl.basic.BasicWarehousesServiceImpl;
import com.ruoyi.system.service.impl.transport.TransportTaskServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TradeCargoOrderServiceImpl implements ITradeCargoOrderService {

    @Resource
    private TradeCargoOrderMapper tradeCargoOrderMapper;

    @Resource
    private OrderWarehouseStateMapper orderWarehouseStateMapper;

    @Resource
    private BasicWarehousesMapper basicWarehousesMapper;

    /**
     * 这里用了ServiceImpl，只是为了更快调用，不太符合分层的逻辑
     */
    @Resource
    private TradeCargoOrderServiceImpl tradeCargoOrderService;

    @Resource
    private TransportTaskServiceImpl transportTaskService;

    @Resource
    private BasicWarehousesServiceImpl basicWarehousesService;


    @Override
    public TradeCargoOrderVo selectCargoOrderByOrderId(Long orderId) {
        TradeCargoOrderVo tradeCargoOrderVo = new TradeCargoOrderVo();
        if(orderId != null){
            TradeCargoOrderDto tradeCargoOrderDto = tradeCargoOrderMapper.selectTradeCargoOrderByOrderId(orderId);
            tradeCargoOrderVo = dtoToVo(tradeCargoOrderDto);
        }
        return tradeCargoOrderVo;
    }

    @Override
    public List<TradeCargoOrderVo> selectTradeCargoOrderList(TradeCargoOrder tradeCargoOrder) {
        List<TradeCargoOrderDto> tradeCargoOrderDtos = tradeCargoOrderMapper.selectTradeCargoOrderList(tradeCargoOrder);
        return tradeCargoOrderDtos.stream().map(this::dtoToVo).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public int insertTradeCargoOrder(TradeCargoOrder tradeCargoOrder) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Date nowDate = DateUtils.getNowDate();
        tradeCargoOrder.setCreateTime(nowDate);
        tradeCargoOrder.setCreateBy(loginUser.getUser().getUserId());
        tradeCargoOrder.setPrice(getPrice(tradeCargoOrder)); // 路程*类型*重量
        tradeCargoOrder.setState(CargoStateConstant.WAITING); // 状态待接收
        // 生成订单
        int i = tradeCargoOrderMapper.insertTradeCargoOrder(tradeCargoOrder);
        // 查询订单号
        Long orderId = tradeCargoOrderMapper.selectOrderIdByCreatetimeAndUserId(loginUser.getUser().getUserId(), nowDate);
        OrderWarehouseState orderWarehouseState = new OrderWarehouseState();
        orderWarehouseState.setOrderId(tradeCargoOrder.getOrderId());
        orderWarehouseState.setTaskId(null);
        orderWarehouseState.setState(WarehouseStateConstant.IN);
        orderWarehouseState.setCreateTime(nowDate);
        // 获取仓库 通过区县和乡镇
        BasicWarehouses basicWarehouses = basicWarehousesMapper.selectWarehouseIdByDistrictAndTown(tradeCargoOrder.getDepartureDistrict(), tradeCargoOrder.getDepartureTown());
        orderWarehouseState.setWarehouseId(basicWarehouses.getWarehouseId());
        orderWarehouseState.setCreateBy(basicWarehouses.getManagerId());
        orderWarehouseStateMapper.insert(orderWarehouseState);
        return i;
    }

    /**
     * 获取订单收费
     * @param tradeCargoOrder
     * @return
     */
    private int getPrice(TradeCargoOrder tradeCargoOrder){
        return getUnitPrice(
                tradeCargoOrder.getDepartureDistrict(), tradeCargoOrder.getDestinationDistrict(),
                tradeCargoOrder.getDepartureTown(), tradeCargoOrder.getDestinationTown()
        ) * Integer.parseInt(tradeCargoOrder.getCargoTypeId().toString()) * tradeCargoOrder.getWeight();
    }

    @Override
    public int updateTradeCargoOrder(TradeCargoOrder tradeCargoOrder) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Date nowDate = DateUtils.getNowDate();
        tradeCargoOrder.setUpdateBy(loginUser.getUser().getUserId());
        tradeCargoOrder.setUpdateTime(nowDate);
        tradeCargoOrder.setPrice(getPrice(tradeCargoOrder));
        return tradeCargoOrderMapper.updateTradeCargoOrder(tradeCargoOrder);
    }

    @Override
    public int deleteTradeCargoOrderByOrderIds(List<Long> orderIds) {
        return tradeCargoOrderMapper.deleteTradeCargoOrderByOrderIds(orderIds);
    }

    @Override
    public int deleteTradeCargoOrderByOrderId(Long orderId) {
        return tradeCargoOrderMapper.deleteTradeCargoOrderByOrderId(orderId);
    }

    /**
     * 查询订单的状况（当前的运输路径）
     */
    @Override
    public List<OrderWarehouseStateVo> searchList(Long orderId) {
        List<OrderWarehouseStateDto> orderWarehouseStateDtos = orderWarehouseStateMapper.queryOrderWarehouseStateByOrderId(orderId);
        List<OrderWarehouseStateVo> result = new ArrayList<>();
        for (OrderWarehouseStateDto orderWarehouseStateDto : orderWarehouseStateDtos) {
            result.add(dtoToVo(orderWarehouseStateDto));
        }
        // 排序操作
//        Comparator<OrderWarehouseStateVo> comparator = Comparator.comparing(OrderWarehouseStateVo::getCreateTime);
        Collections.sort(result, Comparator.comparing(OrderWarehouseStateVo::getCreateTime));
        return result;
    }

    private OrderWarehouseStateVo dtoToVo(OrderWarehouseStateDto dto) {
        OrderWarehouseStateVo vo = new OrderWarehouseStateVo();
        // 获取对应task
        TransportTaskVo transportTaskVo = transportTaskService.selectTransportTaskByTaskId(dto.getTaskId());
        vo.setTask(transportTaskVo);
        // 获取对应order
        TradeCargoOrderVo orderVo = null; // 直接从task中获取order信息，不需要再查一次
        for (TradeCargoOrderDto order : transportTaskVo.getOrders()) {
            if (order.getOrderId() == dto.getOrderId()){
                orderVo = tradeCargoOrderService.dtoToVo(order);
            }
        }
        vo.setOrder(orderVo);
        // 通过basicWarehousesServiceImpl先从dto获取basic对象再转换为WareDto再转换为WareVo
        vo.setWarehouse(basicWarehousesService.DtoConvertToVo(basicWarehousesService.selectBasicWarehousesByWarehouseId(dto.getWarehouse().getWarehouseId())));
        vo.setState(dto.getState());
        vo.setCreateTime(dto.getCreateTime());
        vo.setCreateBy(dto.getCreateBy());
        return vo;
    }

    private TradeCargoOrderVo dtoToVo(TradeCargoOrderDto dto) {
        TradeCargoOrderVo vo = new TradeCargoOrderVo();
        vo.setOrderId(dto.getOrderId());
        vo.setBasicCargoTypes(dto.getBasicCargoTypes());
        vo.setWeight(dto.getWeight());
        vo.setDepartureAddress(dto.getDepartureAddress());
        vo.setDepartureDistrict(dto.getDepartureDistrict());
        vo.setDepartureTown(dto.getDepartureTown());
        vo.setDestinationAddress(dto.getDestinationAddress());
        vo.setDestinationDistrict(dto.getDestinationDistrict());
        vo.setDestinationTown(dto.getDestinationTown());
        vo.setPosterName(dto.getPosterName());
        vo.setPosterPhoneNumber(dto.getPosterPhoneNumber());
        vo.setReceiverName(dto.getReceiverName());
        vo.setReceiverPhoneNumber(dto.getReceiverPhoneNumber());
        vo.setPrice(dto.getPrice());
        vo.setState(dto.getState());
        vo.setCreateBy(dto.getCreateBy());
        vo.setCreateTime(dto.getCreateTime());
        vo.setUpdateTime(dto.getUpdateTime());
        return vo;
    }

    /**
     * 获取运输距离收费（每段运输每公斤1块）
     * @param startDistrict
     * @param endDistrict
     * @param startTown
     * @param endTown
     * @return
     */
    public Integer getUnitPrice(String startDistrict, String endDistrict, String startTown, String endTown){
        if (startDistrict.equals(endDistrict)){
            if (startTown.equals(endTown)){
                return 2; // 点-镇-点
            } else {
                return 4; // 点-镇-区-镇-点
            }
        }else{
            return 6; // 点-镇-区-市-区-镇-点
        }
    }
}
